using System;
using System.Collections.Generic;
using System.Text;
using LibGreen.Jabber.ProtocolElements;
using LibGreen.Jabber.Connection;

namespace LibGreen.Jabber.Managers
{
    /// <summary>
    /// Describes a message received event
    /// </summary>
    public class MessageReceivedEventArgs : EventArgs
    {
        private readonly DateTime timestamp = DateTime.Now;
        private readonly Jid from;
        private readonly string message;

        /// <summary>
        /// Initializes a new MessageReceivedEventArgs
        /// </summary>
        /// <param name="from">The <see cref="Jid"/> of the entity that sent the message</param>
        /// <param name="message">The received message</param>
        public MessageReceivedEventArgs(Jid from, string message)
        {
            this.from = from;
            this.message = message;
        }

        /// <summary>
        /// Gets the <see cref="Jid"/> of the entity that sent the message
        /// </summary>
        public Jid From
        {
            get { return from; }
        }

        /// <summary>
        /// Gets the received message
        /// </summary>
        public string Message
        {
            get { return message; }
        }
    }

    /// <summary>
    /// A handler for message received events
    /// </summary>
    /// <param name="sender">The <see cref="MessageManager"/> raising the event</param>
    /// <param name="e">A <see cref="MessageReceivedEventArgs"/> describing the event</param>
    public delegate void MessageReceivedEventHandler(object sender, MessageReceivedEventArgs e);

    /// <summary>
    /// Controls the flow of chat messages
    /// </summary>
    public class MessageManager
    {
        /// <summary>
        /// Raised when an entity sends a message to the client
        /// </summary>
        public event MessageReceivedEventHandler MessageReceived;

        private readonly Session parentSession;

        /// <summary>
        /// Initializes a new MessageManager
        /// </summary>
        /// <param name="parentSession">The <see cref="Session"/> that owns this manager</param>
        public MessageManager(Session parentSession)
        {
            this.parentSession = parentSession;
        }

        /// <summary>
        /// Sends a plaintext message to a remote user
        /// </summary>
        /// <param name="to">The <see cref="Jid"/> of the destination of the message</param>
        /// <param name="message">The plaintext message to send</param>
        /// <exception cref="NotLoggedInException">Thrown when the client is not logged in</exception>
        public void SendMessage(Jid to, string message)
        {
            if (!OkayToSend)
            {
                throw new NotLoggedInException();
            }

            Connection.SendXmppElement(
                MessageElement.Create(parentSession.JID, to, message));
        }

        #region Private methods
        /// <summary>
        /// Raises the <see cref="MessageReceived"/> event
        /// </summary>
        /// <param name="from">The <see cref="Jid"/> of the entity sending the message</param>
        /// <param name="message">The received message</param>
        protected internal void OnMessageReceived(Jid from, string message)
        {
            if (MessageReceived != null)
            {
                MessageReceived(this, new MessageReceivedEventArgs(from, message));
            }
        }

        /// <summary>
        /// Gets the session's XmppConnection
        /// </summary>
        private XmppConnection Connection
        {
            get { return parentSession.ServerConnection; }
        }

        /// <summary>
        /// Gets a value indicating whether the session is able to send packets
        /// </summary>
        private bool OkayToSend
        {
            get { return parentSession.ServerConnection != null && parentSession.ServerConnection.State == ConnectionState.Connected; }
        }
        #endregion
    }
}
